package graphics;

import graphics.shapes.Ball;
import graphics.tools.CollisionDetection;
import graphics.tools.Light;
import graphics.tools.OrbitBehavior;

import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.vecmath.Point3d;

import com.sun.j3d.utils.universe.SimpleUniverse;

/**
 * The main SceneGraph(BranchGroup) of the program
 * 
 * @author: Eirik Vigeland
 * @version: %I%, %G%
 */
public class SceneGraph extends BranchGroup {

	private BoundingSphere bounds;
	private OrbitBehavior orbit;
	private SimpleUniverse su;
	private CollisionDetection cd;
	private Canvas3D cv;

	/**
	 * Constructor
	 * 
	 * @param su
	 *            SimpleUniverse used in the program for setting the view
	 *            platform
	 * @param cv
	 *            Canvas3D added to the the OrbitBehavior and to be distributed
	 *            to objects in the scene.
	 */
	public SceneGraph(SimpleUniverse su, Canvas3D cv) {
		this.cv = cv;
		this.su = su;
		bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
		orbit = new OrbitBehavior(cv);
		orbit.setSchedulingBounds(bounds);
		su.getViewingPlatform().setViewPlatformBehavior(orbit);
		capability();
		cd = new CollisionDetection();

		Ball rootNode = new Ball(cd);
		cd.add(rootNode.getShapeBounds());
		rootNode.rootNodeColor();
		addChild(rootNode);
		rootNode.hasParent();

		new Light(bounds, this);
	}

	/**
	 * Setting the capability of the BranchGroup to accept and detach objects.
	 */
	public void capability() {
		setCapability(BranchGroup.ALLOW_DETACH);
		setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND);
		setCapability(BranchGroup.ALLOW_CHILDREN_READ);
		setCapability(BranchGroup.ALLOW_CHILDREN_WRITE);
	}

	/**
	 * Returning the Canvas3D to objects in the SceneGraph
	 * 
	 * @return Canvas3D main display of the universe
	 */
	public Canvas3D getCanvas() {
		return cv;
	}

	/**
	 * Returning the Orbit behavior to objects in the SceneGraph
	 * 
	 * @return OrbitBahavior the universe orbit
	 */
	public OrbitBehavior getOrbit() {
		return orbit;
	}

	/**
	 * Sets the Orbit behavior in the SceneGraph
	 * 
	 * @param orbit
	 */
	public void setOrbit(OrbitBehavior orbit) {
		this.orbit = orbit;
	}

	/**
	 * Returning the Simple universe to objects in the SceneGraph
	 * 
	 * @return SimpleUniverse the universe
	 */
	public SimpleUniverse getSu() {
		return su;
	}
}
